python threading模块(全) 您所在的位置:网站首页 python threading模块安装 python threading模块(全)

python threading模块(全)

2023-07-14 12:41| 来源: 网络整理| 查看: 265

        一、线程与进程的介绍参考之前写的VC++的多线程与互斥对象:

 https://blog.csdn.net/Gordennizaicunzai/article/details/52268343

        二、python全局解析器锁(GIL)。

        python代码相对于其它语言在多线程效率上有个“先天性缺陷”——python有个虚拟机(又名解析器主循环)对代码进行执行控制,在解析器主循环中单位时间内只能有一个控制线在执行。意思是任意时刻只能有一个程序在运行,即使内存中有多个程序。python通过GIL对虚拟机进行访问:

        1、设置GIL。

        2、切换进一个线程去运行。

        3、执行下面操作之一:

                a. 指定数量的字节码指令。

                b. 线程主动让出控制权(可以调用time.sleep(0))来完成。

        4、把线程设置回睡眠状态(切换退出线程)。

        5、解锁GIL。

        6、重复1~5。

        对效率要求非常高的python开发中,倾向于这样设计:

        IO密集型(不用CPU)——多线程

        计算密集型(用CPU)——多进程

        三、Threading模块的对象。 对象描述Thread表示一个执行线程的对象。Lock锁原语对象(和thread模块中的锁一样)。Rlock可重入锁对象,使单一线程可以(再次)获得已持有的锁(递归锁)。Condition条件变量对象,使得一个线程等待另一个线程满足特定的“条件”,比如改变状态或某个数据值。Event条件变量的通用版本,任意数量的线程等待某个事件的发生,在该事件发生后所有线程将被激活。Semaphore为线程间共享的有限资源提供了一个“计数器”,如果没有可用资源时会被阻塞。BoundedSemaphore与Semahore相似,不过它不允许超过初始值。Timer与Thread相似,不过它要在运行前等待一段时间。Barrier创建一个“障碍”,必须达到指定数量的线程后才可以继续。         3.1、Thread类。 属性或方法描述name线程名,可以用直接赋值进行修改,如Thread.name = 'T1'。ident线程的标识符。daemon布尔标志,True为守护线程,False则不是,可以直接赋值,如Thread.daemon = True。_init_(group=None, tatget=None, name=None, args=(), kwargs={}, verbose=None, daemon=None)实例化一个线程对象,需要有一个可调用的target,以及其参数args(传元祖等iterable)或kwargs。还可以传递name或group参数,不过后者还未实现。此外,verbose标志也是可以接受的。而daemon的值将会设定thread.daemon属性/标志。start()开始执行该线程。run()定义线程功能的方法(通常在子类中被应用开发者重写)。join(timeout=None)直至启动的线程终止之前一直挂起:除非给出了timeout(秒),否则会一直阻塞。自旋锁。is_alive()布尔标志,表示这个线程是否还活着。 >>> import threading >>> import time >>> >>> def thread1(tickets): if tickets 0: print("thread1 sell ticket : %d" % tickets) tickets -= 1 time.sleep(1) return True >>> t1 = threading.Thread(target=thread1,args=(50,)) >>> t1 >>> t1.name 'Thread-4' >>> t1.name = 'T1' >>> t1 >>> t1.name 'T1' >>> t1.daemon False >>> t1.daemon = True >>> t1.daemon True >>> t1.is_alive() False >>> t1.start() thread1 sell ticket : 50 >>> thread1 sell ticket : 49 thread1 sell ticket : 48 thread1 sell ticket : 47 thread1 sell ticket : 46 thread1 sell ticket : 45t1.is_alive() True >>> thread1 sell ticket : 44 thread1 sell ticket : 43 thread1 sell ticket : 42 thread1 sell ticket : 41 thread1 sell ticket : 40 thread1 sell ticket : 39 thread1 sell ticket : 38 print('Y') Y >>> thread1 sell ticket : 37 thread1 sell ticket : 36 thread1 sell ticket : 35 thread1 sell ticket : 34 thread1 sell ticket : 33 thread1 sell ticket : 32 t1.join() # 启用join,下面将一直阻塞,直到T1运行结束 thread1 sell ticket : 31 thread1 sell ticket : 30 thread1 sell ticket : 29 thread1 sell ticket : 28 thread1 sell ticket : 27 thread1 sell ticket : 26 thread1 sell ticket : 25 thread1 sell ticket : 24 thread1 sell ticket : 23 thread1 sell ticket : 22 thread1 sell ticket : 21 thread1 sell ticket : 20 thread1 sell ticket : 19 thread1 sell ticket : 18 thread1 sell ticket : 17 thread1 sell ticket : 16 thread1 sell ticket : 15 thread1 sell ticket : 14 thread1 sell ticket : 13 thread1 sell ticket : 12 thread1 sell ticket : 11 thread1 sell ticket : 10 thread1 sell ticket : 9 thread1 sell ticket : 8 thread1 sell ticket : 7 thread1 sell ticket : 6 thread1 sell ticket : 5 thread1 sell ticket : 4 thread1 sell ticket : 3 thread1 sell ticket : 2 thread1 sell ticket : 1 >>> print('Y') Y >>>

 

        3.2、Lock类。

        锁有且只有两种状态:锁定和未锁定。获得锁函数用acquire()、 释放锁函数用release()。当多线程争夺锁时,允许第一个获得锁的线程进入临界区,并执行代码,其它后面到达的所有线程都将被阻塞,直到第一个获得锁的那个线程执行结束,退出临界区,并释放锁后,其它等待的线程才可以获得锁并进入临界区。注意,那些被阻塞的线程是没有顺序的,并不是先到先得,而是不确定的。

未加锁:

>>> import threading >>> import time >>> >>> tickets = 50 >>> def thread1(): global tickets # 全局变量 while tickets > 0: print("thread1 sell ticket : %d\r\n" % tickets) tickets -= 1 time.sleep(0.1) return True >>> def thread2(): global tickets # 全局变量 while tickets > 0: print("thread2 sell ticket : %d\r\n" % tickets) tickets -= 1 time.sleep(0.1) return True >>> threads = [] >>> t1 = threading.Thread(target=thread1) >>> threads.append(t1) >>> t2 = threading.Thread(target=thread2) >>> threads.append(t2) >>> >>> for i, t in enumerate(threads): t.start() time.sleep(0.1) thread1 sell ticket : 50 thread2 sell ticket : 49 thread1 sell ticket : 49 >>> thread2 sell ticket : 47 thread1 sell ticket : 47 thread2 sell ticket : 45 thread1 sell ticket : 45 thread2 sell ticket : 43 thread1 sell ticket : 43 thread2 sell ticket : 41 thread1 sell ticket : 41 ......

加锁:

>>> tickets = 20 >>> lock = threading.Lock() >>> >>> def thread1(): global tickets # 全局变量 while tickets > 0: lock.acquire() tickets -= 1 print("thread1 sell ticket : %d\n" % tickets) lock.release() time.sleep(0.2) return True >>> def thread2(): global tickets # 全局变量 while tickets > 0: lock.acquire() tickets -= 1 print("thread2 sell ticket : %d\n" % tickets) lock.release() time.sleep(0.2) return True >>> threads = [] >>> t1 = threading.Thread(target=thread1) >>> threads.append(t1) >>> t2 = threading.Thread(target=thread2) >>> threads.append(t2) >>> >>> for i, t in enumerate(threads): t.start() thread1 sell ticket : 19 >>> thread2 sell ticket : 18 thread1 sell ticket : 17 thread2 sell ticket : 16 thread1 sell ticket : 15 thread2 sell ticket : 14 thread1 sell ticket : 13 thread2 sell ticket : 12 thread1 sell ticket : 11 thread2 sell ticket : 10 thread1 sell ticket : 9 thread2 sell ticket : 8 thread1 sell ticket : 7 thread2 sell ticket : 6 thread1 sell ticket : 5 thread2 sell ticket : 4 thread1 sell ticket : 3 thread2 sell ticket : 2 thread1 sell ticket : 1 thread2 sell ticket : 0         3.3、RLock类。

        RLock和Lock没多大区别。RLock为可重入锁,可以由同一线程多次获取。在内部,除了原始锁使用的锁定/解锁状态之外,它还使用“拥有线程”和“递归级别”的概念。在锁定状态下,某些线程拥有锁; 在解锁状态下,没有线程拥有它。申请和释放必须成对出现:

>>> import threading >>> rLock = threading.RLock() >>> rLock.acquire() True >>> rLock.acquire() True >>> rLock.acquire() True >>> rLock.release() >>> rLock.release() >>> rLock.release() >>> rLock.release() Traceback (most recent call last): File "", line 1, in rLock.release() RuntimeError: cannot release un-acquired lock >>> >>> # 说明RLock的acquire()与release()必须成对出现。 >>> lock.acquire() True >>> lock.acquire() lock.release() lock.release() lock.release() # 已经产生了死锁,没有反应了 lock.release()         3.4、Condition类(更高级的锁)

        

        线程的挂起与阻塞:

  挂起:是因为我们需要进行调度然后认为的暂停某个线程的执行,我们也会主动放下线程实现线程的继续运行

  阻塞:多半是被动的,因为资源访问的竞争,或是线程冲突。

  阻塞的线程挂起放下后依然是阻塞的。

  可以把Condiftion理解为一把高级的锁,它提供了比Lock, RLock更高级的功能,允许我们能够控制复杂的线程同步问题。

  threadiong.Condition在内部维护一个锁对象(默认是RLock),可以在创建Condigtion对象的时候把锁对象作为参数传入。

  condition方法:

  1.acquire():线程获得锁

  2.release():释放锁

  3.wait():wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时(如果提供了timeout参数的话)。当线程被唤醒并重新占有琐的时候,程序才会继续执行下去。。

  4.notify():唤醒一个挂起的线程(如果存在挂起的线程)。注意:notify()方法不会释放所占用的琐。

        5.notifyAll():唤醒所有挂起的线程(如果存在挂起的线程)。注意:这些方法不会释放所占用的琐。

  捉迷藏:

>>> import threading, time >>> >>> class Seeker(threading.Thread): def __init__(self, cond, name): threading.Thread.__init__(self) self.cond = cond self.name = name def run(self): time.sleep(1) # 1.确保seeker晚于hider开始执行 print('1\n') self.cond.acquire() # 4. seeker申请锁 print ('我把眼睛蒙上了\n') self.cond.notify() # 5.蒙上眼后通知hider,hider线程此时被唤醒并试图获取锁,锁将在seeker身上,所以hider会被阻塞,seeker继续往下 self.cond.wait() # 6. seeker锁被释放并且挂起,hider就获取锁开始继续往下运行了 print('2\n') print ('我找到你了\n') self.cond.notify() # 9.找到了之后通知hider,hider意图获取锁但不行所以被阻塞,seeker往下 self.cond.release() # 10.seeker释放锁,以便被通知的hider可以或得到锁 print('3\n') print ('我赢了\n') >>> >>> class Hider(threading.Thread): def __init__(self, cond, name): threading.Thread.__init__(self) self.cond = cond self.name = name def run(self): self.cond.acquire() # 2.hider获取锁 self.cond.wait() # 3.hider被挂起然后释放锁 print('4\n') print ('我已经藏好了\n') self.cond.notify() # 7.藏好后通知seeker,seeker意图获取锁,但是锁在hider身上所以seeker被阻塞 self.cond.wait() # 8.hider被挂起,释放锁,seeker获取锁,seeker继续往下运行 print('5\n') self.cond.release()# 11. 在此句之前一点,seeker释放了锁(#10),hider得到锁,随即这句hider释放锁 print ('被你找到了\n') >>> >>> cond = threading.Condition() >>> seeker = Seeker(cond, 'seeker') >>> hider = Hider(cond, 'hider') >>> threads = [] >>> threads.append(seeker) >>> threads.append(hider) >>> for i, t in enumerate(threads): t.start() >>> 1 我把眼睛蒙上了 4 我已经藏好了 2 我找到你了 5 3 被你找到了 我赢了 >>>         3.5、Event类(利用标志位实现的锁)

        

        Event实现与Condition类似的功能,不过比Condition简单一点。它通过维护内部的标识符来实现线程间的同步问题。

        1.Event.wait() : 堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。

        2.Event.clear() : 将标志位置于false状态。

        3.Event.set() : 设置标志位为true

        4.Event.isSet() : 判断标志位状态

        用Event模拟红绿灯: 

Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license()" for more information. >>> >>> import threading >>> import time >>> >>> def light(event): print('线程阻塞中,启动线程请输入[true]') event.wait() # 阻塞线程,直到Event对象内部的标志位置为True counts = 0 while True: event.clear() print('the light is red') time.sleep(6) if counts < 5: event.set() else: event.wait() break print('the light is green') time.sleep(4) print('the light is yellow') time.sleep(2) counts += 1 >>> >>> def car(event): event.wait() # 阻塞线程,直到Event对象内部的标志位置为True while True: if event.isSet(): print('green or yellow is on ,let`s go!') time.sleep(2) else: print('red in on, we must stop!') time.sleep(2) >>> >>> event = threading.Event() >>> threads = [] >>> t1 = threading.Thread(target=light,args=(event,)) >>> threads.append(t1) >>> t2 = threading.Thread(target=car,args=(event,)) >>> threads.append(t2) >>> for i, t in enumerate(threads): t.start() >>> 线程阻塞中,启动线程请输入[true] >>> start = input >>> start = input() true >>> start 'true' >>> if start == 'true': event.set() green or yellow is on ,let`s go!the light is red >>> red in on, we must stop! red in on, we must stop! the light is greengreen or yellow is on ,let`s go! green or yellow is on ,let`s go! the light is yellowgreen or yellow is on ,let`s go! the light is redred in on, we must stop! red in on, we must stop! red in on, we must stop! the light is green green or yellow is on ,let`s go! green or yellow is on ,let`s go! the light is yellow green or yellow is on ,let`s go! the light is red red in on, we must stop! red in on, we must stop! red in on, we must stop! the light is green green or yellow is on ,let`s go! green or yellow is on ,let`s go! the light is yellow green or yellow is on ,let`s go! the light is red red in on, we must stop! red in on, we must stop! red in on, we must stop! the light is green green or yellow is on ,let`s go! green or yellow is on ,let`s go! the light is yellow green or yellow is on ,let`s go! the light is red red in on, we must stop! red in on, we must stop! red in on, we must stop! the light is green green or yellow is on ,let`s go! green or yellow is on ,let`s go! the light is yellow green or yellow is on ,let`s go! the light is red red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop! red in on, we must stop!         3.6、Semaphore([value])类(信号量)

        values是一个内部计数,values默认是1,如果小于0,则会抛出 ValueError 异常,一般用于控制线程数并发数。

        信号量是最古老的同步原语之一。它是一个计数器,当资源消耗时递减,当资源释放时递增。你可以认为信号量代表它们的资源可用或不可用。信号量比锁更加灵活,因为可以有多个线程共用一个资源的一个实例。

        信号量实际上就相当于一个计算器:

    

        acquire(blocking=布尔值,timeout=None),计数器减1;

        本方法用于获得Semaphore         blocking默认值是True,此时,如果内部计数器值大于0,则减一,并返回;如果等于0,则阻塞,等待其他线程调用release()以使计数器加1;本方法返回True,或无线阻塞 如果blocking=False,则不阻塞,如若获取失败,则返回False。 当设定了timeout的值,最多阻塞timeout秒,如果超时,返回False。

        release(),计数器加1;

        3.7、BoundedSemaphore([value])类(更安全的信号量)

        BoundedSemaphore同Semaphore,不同的是BoundedSemaphore计数器的值永远不会超过它的初始值,它自动防止信号量释放的次数多于获得的次数,所以BoundedSemaphore更安全。

        信号量控制某个时间段内线程数量:

>>> import threading >>> import time >>> >>> MAX_COUNTS = 3 >>> nums = threading.BoundedSemaphore(MAX_COUNTS) >>> >>> def count(n): print('\nacquire time: %s' % time.ctime()) time.sleep(5) nums.release() print('\n%d release time: %s' % (n, time.ctime())) >>> for i in range(MAX_COUNTS*2): nums.acquire() t=threading.Thread(target=count, args=(i,)) t.start() print('\n%s start' % t.name) True acquire time: Sat Aug 24 23:09:04 2019 Thread-1 start True acquire time: Sat Aug 24 23:09:04 2019 Thread-2 start True Thread-3 start acquire time: Sat Aug 24 23:09:04 2019 0 release time: Sat Aug 24 23:09:09 2019True 1 release time: Sat Aug 24 23:09:09 2019 2 release time: Sat Aug 24 23:09:09 2019 Thread-4 start acquire time: Sat Aug 24 23:09:09 2019 True Thread-5 start acquire time: Sat Aug 24 23:09:09 2019 True Thread-6 start acquire time: Sat Aug 24 23:09:09 2019 >>> 3 release time: Sat Aug 24 23:09:14 2019 4 release time: Sat Aug 24 23:09:14 2019 5 release time: Sat Aug 24 23:09:14 2019         3.8、Timer类

        threading.Timer是threading.Thread的子类,可以在指定时间间隔后执行某个操作。通过调用start()方法,启动计时器,就像使用线程一样。通过调用cancel()方法可以停止计时器(在其动作开始之前,只有在计时器仍处于等待阶段时才有效。)。

>>> def fun1(): print("%s I'm fun1" % time.ctime()) >>> def fun2(): print("%s I'm fun2" % time.ctime()) >>> threads = [] >>> t1 = threading.Thread(target=fun1) >>> threads.append(t1) >>> t2 = threading.Timer(5, fun2) # 5s后运行 >>> threads.append(t2) >>> >>> for i, t in enumerate(threads): t.start() Sat Aug 24 23:22:39 2019 I'm fun1 >>> Sat Aug 24 23:22:44 2019 I'm fun2         3.9、Barrier类

        Barrier类是设置了一个线程数量障碍,当等待的线程到达了这个数量就会唤醒所有的等待线程,可用于并发初始化等场景。

 class Barrier(builtins.object)  |  Barrier(parties, action=None, timeout=None)  parties障碍要求的线程数量,action是一个可调用的函数,timeout是wait方法未指定时超时的默认值。  |    |  Implements a Barrier.实现了一个障碍。  |    |  Useful for synchronizing a fixed number of threads at known synchronization  |  points.  Threads block on 'wait()' and are simultaneously awoken once they  |  have all made that call.用于在已知同步点同步固定数量的线程。线程阻塞在'wait()'上,并在所有线程都发出该调用后同时被唤醒。  |    |  Methods defined here:  |    |  __init__(self, parties, action=None, timeout=None)  |      Create a barrier, initialised to 'parties' threads.  |        |      'action' is a callable which, when supplied, will be called by one of  |      the threads after they have all entered the barrier and just prior to  |      releasing them all. If a 'timeout' is provided, it is used as the  |      default for all subsequent 'wait()' calls.“action”是一个可调用的函数,当它被提供时,其中一个线程将在它们全部进入屏障并在释放它们之前调用它。如果提供了“timeout”,它将作为所有后续“wait()”调用的默认值。  |    |  abort(self)  |      Place the barrier into a 'broken' state.将障碍设置为“破碎”状态。  |        |      Useful in case of error.  Any currently waiting threads and threads  |      attempting to 'wait()' will have BrokenBarrierError raised.在出错时有用。任何当前正在等待的线程和试图“wait()”的线程都将引发breakbarriererror异常,直到reset方法来恢复障碍。  |    |  reset(self)  |      Reset the barrier to the initial state.将障碍重置为初始状态,重新开始拦截,相当于电脑的重启按键。  |        |      Any threads currently waiting will get the BrokenBarrier exception  |      raised.当前等待的任何线程都将引发BrokenBarrierError异常。  |    |  wait(self, timeout=None)  |      Wait for the barrier.当前线程进入阻塞状态。  |        |      When the specified number of threads have started waiting, they are all  |      simultaneously awoken. If an 'action' was provided for the barrier, one  |      of the threads will have executed that callback prior to returning.  |      Returns an individual index number from 0 to 'parties-1'.当开始等待的线程数量达到指定数量时,它们都被同时唤醒。如果为障碍提供了一个“action”,其中一个线程将在返回之前执行该回调。 返回从0到“parties-1”的单个索引号。timeout:如果等待超时,则引发BrokenBarrierError异常。

 |  ----------------------------------------------------------------------  |  Data descriptors defined here:  |    |  __dict__  |      dictionary for instance variables (if defined)  |    |  __weakref__  |      list of weak references to the object (if defined)  |    |  broken  |      Return True if the barrier is in a broken state.检测栅栏是否处于打破的状态,返回True或False

 |      abort()  将栅栏置于broken状态,等待中的线程或者调用等待方法的线程都会抛出threading.BrokenBarrieError异常,直到     |      reset方法来恢复栅栏  |    |  n_waiting  |      Return the number of threads currently waiting at the barrier.返回当前在栅栏中等待的线程数  |    |  parties  |      Return the number of threads required to trip the barrier.返回通过栅栏所需的线程数

​ >>> import threading >>> >>> barrier = threading.Barrier(3) >>> >>> import time >>> import threading >>> >>> barrier = threading.Barrier(3) >>> def run(): print('{} current n_waiting: {}'.format(time.ctime(), barrier.n_waiting)) barrier.wait() >>> for i in range(10): time.sleep(0.1) threading.Thread(target=run,name="barrier{}".format(i)).start() Sat Jun 27 15:10:07 2020 current n_waiting: 0 Sat Jun 27 15:10:07 2020 current n_waiting: 1 Sat Jun 27 15:10:08 2020 current n_waiting: 2 Sat Jun 27 15:10:08 2020 current n_waiting: 0 Sat Jun 27 15:10:08 2020 current n_waiting: 1 Sat Jun 27 15:10:08 2020 current n_waiting: 2 Sat Jun 27 15:10:08 2020 current n_waiting: 0 Sat Jun 27 15:10:08 2020 current n_waiting: 1 Sat Jun 27 15:10:08 2020 current n_waiting: 2 Sat Jun 27 15:10:08 2020 current n_waiting: 0 >>> ​ >>> def run(): print('{} current n_waiting: {}\r\n'.format(time.ctime(), barrier.n_waiting)) try: barrier.wait() except threading.BrokenBarrierError as e: print('{}\r\n'.format(e)) >>> for i in range(14): key = input('please input key: \r\n') if key in ['a', 'A']: barrier.abort() # 将栅栏置于broken状态,等待中的线程或者调用等待方法的线程都会抛出threading.BrokenBarrieError异常,直到reset方法来恢复栅栏 elif key in ['r', 'R']: barrier.reset() # 恢复栅栏,重新开始拦截 else: pass threading.Event().wait(1) threading.Thread(target=run).start() please input key: g False please input key: Sat Jun 27 15:50:29 2020 current n_waiting: 0 g False please input key: Sat Jun 27 15:50:36 2020 current n_waiting: 1 g False please input key: Sat Jun 27 15:50:39 2020 current n_waiting: 2 g False Sat Jun 27 15:50:41 2020 current n_waiting: 0 please input key: g False Sat Jun 27 15:50:43 2020 current n_waiting: 1 please input key: g False Sat Jun 27 15:50:45 2020 current n_waiting: 2 please input key: g False Sat Jun 27 15:50:48 2020 current n_waiting: 0 please input key: A False please input key: Sat Jun 27 15:50:55 2020 current n_waiting: 0 g False Sat Jun 27 15:51:32 2020 current n_waiting: 0 please input key: g False Sat Jun 27 15:51:35 2020 current n_waiting: 0 please input key: R False Sat Jun 27 15:51:40 2020 current n_waiting: 0 please input key: g False Sat Jun 27 15:51:46 2020 current n_waiting: 1 please input key: g False Sat Jun 27 15:51:48 2020 current n_waiting: 2 please input key: g False Sat Jun 27 15:51:51 2020 current n_waiting: 0 >>> >>> def fun(barrier:threading.Barrier, n:int): print("n_waiting%d--%s\n" % (barrier.n_waiting, time.ctime())) try: if n < 3: barrier.wait(1) # 设置超时时间1s,然后引发BrokenBarrierError异常,异常被except立刻捕获,后面的语句不会被执行 else: if n == 5: barrier.reset() # 重启障碍 print('******barrier had reset******') b = barrier.wait() print('after barrier %s\n' % b) except threading.BrokenBarrierError: print('Broken barrier in %s--%s\n' % (threading.current_thread(), time.ctime())) >>> barrier = threading.Barrier(3) >>> for i in range(1,15): threading.Event().wait(1) # 延迟1s threading.Thread(target=fun,args=(barrier,i),name='Barrier%d' % i).start() False n_waiting0--Sun Aug 25 12:44:10 2019 False Broken barrier in --Sun Aug 25 12:44:12 2019 n_waiting0--Sun Aug 25 12:44:12 2019 Broken barrier in --Sun Aug 25 12:44:12 2019 False n_waiting0--Sun Aug 25 12:44:13 2019 Broken barrier in --Sun Aug 25 12:44:13 2019 False n_waiting0--Sun Aug 25 12:44:14 2019 Broken barrier in --Sun Aug 25 12:44:14 2019 False n_waiting0--Sun Aug 25 12:44:15 2019 ******barrier had reset****** False n_waiting1--Sun Aug 25 12:44:16 2019 False n_waiting2--Sun Aug 25 12:44:17 2019 after barrier 2 after barrier 0 after barrier 1 False n_waiting0--Sun Aug 25 12:44:18 2019 False n_waiting1--Sun Aug 25 12:44:19 2019 False n_waiting2--Sun Aug 25 12:44:20 2019 after barrier 2 after barrier 0 after barrier 1 False n_waiting0--Sun Aug 25 12:44:21 2019 False n_waiting1--Sun Aug 25 12:44:22 2019 False n_waiting2--Sun Aug 25 12:44:23 2019 after barrier 2 after barrier 1 after barrier 0 False n_waiting0--Sun Aug 25 12:44:24 2019 >>>         四、Threading模块的其它一些函数         4.1、active_count() 

        返回当前活动的Thread对象个数,返回的个数中包含主线程。

>>> counts = threading.active_count() >>> counts 3 >>>         4.2、enumerate()

        返回当前活动的Thread对象列表。

>>> threads = threading.enumerate() >>> threads [, , ] >>>

        

        4.3、current_thread

        返回当前的Thread对象。

>>> thread = threading.current_thread >>> thread >>>

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有